package com.example.common.mvi

import android.os.Bundle // Android Bundle类
import android.widget.Toast // Toast消息
import androidx.appcompat.app.AppCompatActivity // AppCompat Activity基类
import androidx.databinding.DataBindingUtil // 数据绑定工具
import androidx.databinding.ViewDataBinding // 数据绑定基类
import androidx.lifecycle.lifecycleScope // Activity生命周期协程作用域
import kotlinx.coroutines.launch // 启动协程

/**
 * MVI架构的基础Activity
 * 处理数据绑定、状态观察、事件处理
 * @param VDB ViewDataBinding类型 - 数据绑定类
 * @param VM ViewModel类型 - 视图模型
 * @param I Intent类型 - 用户意图
 * @param S ViewState类型 - 视图状态
 */
abstract class BaseActivity<VDB : ViewDataBinding, VM : BaseViewModel<I, S, *>, I : MviIntent, S : MviViewState> : AppCompatActivity() {

    protected lateinit var binding: VDB // 数据绑定实例
    protected abstract val viewModel: VM // 抽象的ViewModel，子类必须实现

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) // 调用父类方法
        binding = DataBindingUtil.setContentView(this, getLayoutId()) // 设置数据绑定
        binding.lifecycleOwner = this // 设置生命周期所有者，用于自动管理LiveData
        
        setupViews() // 设置视图
        observeViewModel() // 观察ViewModel
    }

    /**
     * 观察ViewModel的状态和事件
     * 私有方法，在onCreate中自动调用
     */
    private fun observeViewModel() {
        // 观察ViewState变化
        lifecycleScope.launch { // 在生命周期协程中执行
            viewModel.viewState.collect { state -> // 收集状态流
                renderViewState(state) // 渲染新状态到UI
            }
        }

        // 观察单次事件
        lifecycleScope.launch { // 在生命周期协程中执行
            viewModel.singleEvent.collect { event -> // 收集事件流
                handleSingleEvent(event) // 处理单次事件
            }
        }
    }

    /**
     * 处理单次事件
     * 可以被子类重写来自定义事件处理
     */
    protected open fun handleSingleEvent(event: SingleEvent) {
        when (event) { // 根据事件类型处理
            is SingleEvent.ShowToast -> { // 显示Toast消息
                Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show()
            }
            is SingleEvent.ShowError -> { // 显示错误消息
                Toast.makeText(this, event.error, Toast.LENGTH_LONG).show()
            }
            is SingleEvent.Navigate -> { // 页面导航
                handleNavigation(event.route) // 调用导航处理方法
            }
            is SingleEvent.ShowLoading -> { // 显示加载状态
                showLoading() // 调用显示加载方法
            }
            is SingleEvent.HideLoading -> { // 隐藏加载状态
                hideLoading() // 调用隐藏加载方法
            }
        }
    }

    /**
     * 发送Intent到ViewModel
     * 子类调用此方法来发送用户意图
     */
    protected fun sendIntent(intent: I) {
        viewModel.sendIntent(intent) // 委托给ViewModel处理
    }

    /**
     * 获取布局ID的抽象方法
     * 子类必须实现此方法来提供布局资源ID
     */
    protected abstract fun getLayoutId(): Int

    /**
     * 设置视图的抽象方法
     * 子类必须实现此方法来初始化视图
     */
    protected abstract fun setupViews()

    /**
     * 渲染ViewState的抽象方法
     * 子类必须实现此方法来根据状态更新UI
     */
    protected abstract fun renderViewState(state: S)

    /**
     * 处理导航的方法
     * 子类可以重写此方法来自定义导航逻辑
     */
    protected open fun handleNavigation(route: String) {
        // 默认实现为空，子类可重写
    }
    /**
     * 显示加载状态
     * 子类可以重写此方法来自定义加载UI
     */
    protected open fun showLoading() {
        // 默认实现为空，子类可重写
    }
    /**
     * 隐藏加载状态
     * 子类可以重写此方法来自定义加载UI
     */
    protected open fun hideLoading() {
        // 默认实现为空，子类可重写
    }
}